home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 235_01 / cvthlp.c < prev    next >
Text File  |  1987-06-16  |  12KB  |  404 lines

  1. /*  004  12-Jan-87  cvthlp.c
  2.  
  3.         This program converts a text help file to "compiled" format
  4.         used by OverView.
  5.  
  6.         Copyright (c) 1987 by Blue Sky Software.  All rights reserved.
  7. */
  8.  
  9. #define VERSION "Cvthlp 1.01 12-Jan-87"
  10.  
  11. #include <stdio.h>
  12. #include <fcntl.h>
  13.  
  14. unsigned long offset = 0;
  15.  
  16. char inbuf[4096], outbuf[4096];
  17.  
  18. int verbose = 0;
  19. FILE *inf, *outf;
  20. char line[81], *infile, *outfile;
  21.  
  22. #define TXTLINES 24
  23. #define MENUENTS 20
  24.  
  25. unsigned char nmenu, ntext;
  26. char menuent[MENUENTS][81], textlin[TXTLINES][81], header[81];
  27.  
  28. char *strchr();
  29. long ftell(), findframe();
  30.  
  31.  
  32. /******************************************************************************
  33.                                 M A I N
  34.  *****************************************************************************/
  35.  
  36. main(argc,argv)
  37. int argc;
  38. char **argv;
  39. {
  40.    /* process the command line arguments */
  41.  
  42.    do_args(argc,argv);
  43.  
  44.    /* assume user does't know what he is doing if I/O is to/from tty */
  45.  
  46.    if (isatty(fileno(inf)) || isatty(fileno(outf)))
  47.       usage();
  48.  
  49.    setmode(fileno(outf),O_BINARY);     /* need binary mode on output */
  50.  
  51.    /* use big buffers size for in/out files */
  52.  
  53.    setvbuf(inf,inbuf,_IOFBF,sizeof(inbuf));
  54.    setvbuf(outf,outbuf,_IOFBF,sizeof(outbuf));
  55.  
  56.    /* convert the file */
  57.  
  58.    pass1();                    /* pass 1, transform text file to frame fmt */
  59.  
  60.    fclose(inf);                /* close pass 1 files */
  61.    fclose(outf);
  62.  
  63.    if ((outf = fopen(outfile,"r+")) == NULL) {
  64.       perror("Can't reopen out file");
  65.       exit(2);
  66.    }
  67.  
  68.    setmode(fileno(outf),O_BINARY);             /* need binary mode on output */
  69.    setvbuf(outf,outbuf,_IOFBF,sizeof(outbuf)); /* use a big buffer */
  70.  
  71.    pass2();                    /* pass 2, fixup offsets in output file */
  72.  
  73.    fclose(outf);
  74. }
  75.  
  76.  
  77. /******************************************************************************
  78.                                 P A S S 1
  79.  ******************************************************************************/
  80.  
  81. static int
  82. pass1() {              /* transform text help file to frame format */
  83.  
  84.    int i;
  85.  
  86.    *line = ' ';                /* force an initial file read */
  87.  
  88.    while (read_txt_frame()) {
  89.  
  90.       /* write the help frame data to the output file */
  91.  
  92.       fputs(header,outf);              /* output the frame header line */
  93.  
  94.       fputc(nmenu,outf);               /* # menu entries */
  95.  
  96.       for (i = 0; i < nmenu; i++) {    /* do all menu entries */
  97.          fwrite(&offset,sizeof(offset),1,outf);    /* offset to ent's frame */
  98.          fputs(menuent[i],outf);                   /* keyword/prompt string */
  99.       }
  100.  
  101.       fputc(ntext,outf);               /* # text lines */
  102.  
  103.       for (i = 0; i < ntext; i++)      /* do all text lines */
  104.          fputs(textlin[i],outf);
  105.    }
  106. }
  107.  
  108.  
  109. /******************************************************************************
  110.                       R E A D _ T X T _ F R A M E
  111.  ******************************************************************************/
  112.  
  113. static int
  114. read_txt_frame() {            /* read a text help frame */
  115.  
  116.    if (feof(inf))
  117.       return(0);
  118.  
  119.    if (*line != '#')                       /* read till next header line */
  120.       while (readlin() && *line != '#')    /* (doesn't read if already there */
  121.          if (verbose)
  122.             fprintf(stderr,"Skipping: %s\n",line);
  123.  
  124.    if (*line == '#') {
  125.       strcpy(header,line);             /* save header line less # */
  126.  
  127.       if (verbose)
  128.          fprintf(stderr,"Header: %s",header);
  129.  
  130.       /* read the text and menu segments */
  131.  
  132.       nmenu = ntext = 0;
  133.  
  134.       readlin();
  135.  
  136.       if (strnicmp(line,"TEXT",4) == 0) {
  137.          read_txt_text();
  138.          readlin();
  139.       }
  140.  
  141.       if (strnicmp(line,"MENU",4) == 0) {
  142.          read_txt_menu();
  143.          readlin();
  144.       }
  145.  
  146.       if (nmenu == 0 && ntext == 0)
  147.          fprintf(stderr,"No menu or text section for %s",header);
  148.  
  149.       return(1);
  150.    }
  151.  
  152.    return(0);
  153. }
  154.  
  155.  
  156. /*****************************************************************************
  157.                           R E A D _ T X T _ T E X T
  158.  *****************************************************************************/
  159.  
  160. static int
  161. read_txt_text() {      /* read text section */
  162.  
  163.    while (readlin() && strnicmp(line,"TXET",4) != 0 && ntext < TXTLINES)
  164.       strcpy(textlin[ntext++],line);
  165.  
  166.    if (ntext == TXTLINES && strnicmp(line,"TXET",4) != 0) {
  167.       fprintf(stderr,"More than %d lines of text for %s",TXTLINES,header);
  168.       while (readlin() && strnicmp(line,"TXET",4) != 0)
  169.          ;
  170.    }
  171. }
  172.  
  173.  
  174. /*****************************************************************************
  175.                         R E A D _ T X T _ M E N U
  176.  *****************************************************************************/
  177.  
  178. static int
  179. read_txt_menu() {      /* read menu section */
  180.  
  181.    while (readlin() && strnicmp(line,"UNEM",4) != 0 && nmenu < MENUENTS)
  182.       strcpy(menuent[nmenu++],line);
  183.  
  184.    if (nmenu == MENUENTS && strnicmp(line,"UNEM",4) != 0) {
  185.       fprintf("More than %d menu entries for %s",MENUENTS,header);
  186.       while (readlin() && strnicmp(line,"UNEM",4) != 0)
  187.          ;
  188.    }
  189. }
  190.  
  191.  
  192. /******************************************************************************
  193.                               R E A D L I N
  194.  ******************************************************************************/
  195.  
  196. static int
  197. readlin() {            /* read a line */
  198.  
  199.    char buf[512];
  200.  
  201.    if (fgets(buf,sizeof(buf),inf)) {
  202.       if (strlen(buf) > 80) {
  203.          buf[81] = '\0';
  204.          if (verbose)
  205.             fprintf(stderr,"Truncated: %.65s\n",buf);
  206.       }
  207.       strcpy(line,buf);
  208.       return(1);
  209.    }
  210.  
  211.    return(0);
  212. }
  213.  
  214.  
  215. /******************************************************************************
  216.                                 P A S S 2
  217.  ******************************************************************************/
  218.  
  219. static int
  220. pass2() {              /* reread the frame file and fixup the frame offsets */
  221.  
  222.    while (fixframe())          /* fixup all the help frames */
  223.       ;
  224. }
  225.  
  226.  
  227. /******************************************************************************
  228.                              F I X F R A M E
  229.  ******************************************************************************/
  230.  
  231. static int
  232. fixframe() {           /* fixup the current help frame */
  233.  
  234.    unsigned long offsetloc, frameloc;
  235.  
  236.    if (fgets(header,sizeof(header),outf) == NULL)    /* get frame header */
  237.       return(0);                                     /* done if EOF */
  238.  
  239.    nmenu = fgetc(outf);                /* get # menu entries */
  240.  
  241.    while (nmenu--) {
  242.  
  243.       offsetloc = ftell(outf);         /* this is the loc to fixup */
  244.  
  245.       fread(&frameloc,sizeof(frameloc),1,outf);  /* read dummy offset */
  246.       fgets(line,sizeof(line),outf);   /* read menu item */
  247.  
  248.       frameloc = findframe();          /* find the frame for this menu item */
  249.  
  250.       fseek(outf,offsetloc,SEEK_SET);  /* back to the menu offset location */
  251.  
  252.       fwrite(&frameloc,sizeof(frameloc),1,outf);    /* offset to ent's frame */
  253.  
  254.       fseek(outf,0L,SEEK_CUR);         /* seek nowhere just so we can read */
  255.  
  256.       fgets(line,sizeof(line),outf);   /* reread current menu item */
  257.    }
  258.  
  259.    /* just skip over the text lines to find next frame */
  260.  
  261.    skip_txt();
  262.  
  263.    return(1);                  /* another frame processed */
  264. }
  265.  
  266.  
  267. /******************************************************************************
  268.                            F I N D F R A M E
  269.  ******************************************************************************/
  270.  
  271. static long
  272. findframe() {          /* find the frame whose name is in line */
  273.  
  274.    int nummenu;
  275.    long frameloc;
  276.    char *cp, name[81];
  277.  
  278.    if (cp = strchr(line,' ')) {        /* isolate frame name from menu line */
  279.       *name = '\0';
  280.       strncat(name,line,cp-line);
  281.    } else {
  282.       fprintf(stderr,"Bad menu ent in findframe: %s\n",line);
  283.       exit(2);
  284.    }
  285.  
  286.    /* skip to the end of the current frame */
  287.  
  288.    nummenu = nmenu;
  289.    w